<template>
  <div class="page">
    <div class="page_left">
      <el-tabs type="border-card" :before-leave="beforeLeave">
        <el-tab-pane label="html" />
        <el-tab-pane label="javascript"></el-tab-pane>
        <el-tab-pane label="css"></el-tab-pane>
        <el-tab-pane label="刷新"></el-tab-pane>
        <!-- <el-tab-pane label="引入js"></el-tab-pane>
        <el-tab-pane label="引入css"></el-tab-pane> -->
      </el-tabs>
      <div v-show="activeTab === 'html'" id="editorHtml" style="height: 100%;width: 100%;" />
      <div v-show="activeTab === 'js'" id="editorJs" style="height: 100%;width: 100%;" />
      <div v-show="activeTab === 'css'" id="editorCss" style="height: 100%;width: 100%;" />
    </div>
    <div class="page_right">
      <iframe v-show="isCompile" ref="previewPage" class="result-wrapper" frameborder="0" src="preview.html" />
      <div v-show="!isCompile" class="dummy-status">
        <svg-icon class="icon_svg" icon-class="compilation-fails" />
        <span class="icon_span">{{ compileTitle }}</span>
      </div>
    </div>
  </div>
</template>

<script>
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'
import { parse } from '@babel/parser'

export default {
  name: 'Home',
  data() {
    return {
      // 当前代码编辑所在模块（默认html模块）
      activeTab: 'html',
      // 代码编辑模块
      editorObj: {
        html: null,
        js: null,
        css: null
      },
      // 代码编辑内容
      htmlCode: '',
      jsCode: 'export default {}',
      cssCode: '',
      // 编译是否正常
      isCompile: true,
      compileTitle: '编译失败'
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    /**
     * 初始化
     */
    init() {
      this.setEditorValue('editorHtml', 'html', this.htmlCode)
      this.setEditorValue('editorJs', 'js', this.jsCode)
      this.setEditorValue('editorCss', 'css', this.cssCode)
    },
    /**
     * 选项卡切换
     */
    beforeLeave(item) {
      console.log('点击选项卡', item)
      // 刷新项目
      if (Number(item) === 3) this.runCode()
      if (Number(item) > 2) return false
      const mode = ['html', 'js', 'css']
      this.activeTab = mode[item]
      return true
    },
    /**
     * 初始化编辑组件
     * id 初始化模块id
     * type 初始化模块
     * codeStr 初始化代码
     */
    setEditorValue(id, type, codeStr) {
      const mode = {
        html: 'html',
        js: 'javascript',
        css: 'css'
      }
      this.editorObj[type] = monaco.editor.create(document.getElementById(id), {
        value: codeStr,
        theme: 'vs-dark',
        language: mode[type],
        automaticLayout: true
      })
      const code = {
        html: 'htmlCode',
        js: 'jsCode',
        css: 'cssCode'
      }
      this.editorObj[type].onDidChangeModelContent(() => {
        const newValue = this.editorObj[type].getValue()
        this[code[type]] = newValue
      })
    },
    /**
     * 开始编译
     */
    runCode() {
      const jsCodeStr = this.editorObj.js.getValue()
      try {
        this.isCompile = true
        const ast = parse(jsCodeStr, { sourceType: 'module' })
        const astBody = ast.program.body
        if (astBody.length > 1) {
          console.log('js格式不能识别，仅支持修改export default的对象内容')
          this.isCompile = false
          return
        }
        const postData = {
          type: 'refreshFrame',
          data: {
            html: this.editorObj.html.getValue(),
            js: jsCodeStr.replace('export default', ''),
            css: this.editorObj.css.getValue(),
            scripts: [],
            links: []
          }
        }
        this.$refs.previewPage.contentWindow.postMessage(postData, location.origin)
      } catch (err) {
        this.isCompile = false
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.page {
  width: 100%;
  height: 100%;
  display: flex;
  .page_left {
    width: 50%;
    height: 100%;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    ::v-deep .el-tabs {
      margin: 0;
    }
    ::v-deep .el-tabs__content {
      height: 0;
      padding: 0;
    }
  }
  .page_right {
    width: 50%;
    height: 100%;
    .result-wrapper {
      width: 100%;
      height: 100%;
    }
    // 空状态
    .dummy-status {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      .icon_svg {
        width: 200px;
        height: 200px;
      }
      .icon_span {
        -webkit-user-select: none;
        user-select: none;
        font-size: 1.2rem;
        color: #bfbfbf;
      }
    }
  }
}
</style>
